package kr.pe.osdev.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import kr.pe.osdev.common.constant.OsdevConstants;
import kr.pe.osdev.common.util.KeyGenerator;
import kr.pe.osdev.dao.AnswerDao;
import kr.pe.osdev.dao.CommentaryDao;
import kr.pe.osdev.dao.ItemDao;
import kr.pe.osdev.dao.QuestionDao;
import kr.pe.osdev.domain.Answer;
import kr.pe.osdev.domain.Commentary;
import kr.pe.osdev.domain.Item;
import kr.pe.osdev.domain.Question;
import kr.pe.osdev.domain.User;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class QuestionServiceImpl implements QuestionService {
    @Autowired
    private QuestionDao questionDao;
    @Autowired
    private AnswerDao answerDao;
    @Autowired
    private ItemDao itemDao;
    @Autowired
    private CommentaryDao commentaryDao;
    
    public void setQuestionDao(QuestionDao questionDao) {
        this.questionDao = questionDao;
    }
    
    public void setAnswerDao(AnswerDao answerDao) {
        this.answerDao = answerDao;
    }
    
    public void setItemDao(ItemDao itemDao) {
        this.itemDao = itemDao;
    }
    
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    @Override
    public Question add(Question question) throws DataAccessException {
        String generatedKey = KeyGenerator.generatorKey();
        question.setSid(generatedKey);
        
        if(StringUtils.isEmpty(question.getClassification())) {
            question.setClassification(OsdevConstants.CLASSCIFICATION_CODE_DEFAULT);
        }
        
        questionDao.add(question);
        
        if (question.getAnswer() != null && StringUtils.isNotEmpty(question.getAnswer().getAnswer())) {
            Answer answer = question.getAnswer();
            answer.setSid(generatedKey);
            answer.setQuestionSid(question.getSid());
            answer.setAnswerCode(question.getPatternCode());
            
            answerDao.add(answer);
        }
        
        if (OsdevConstants.CLASSCIFICATION_CODE_MULTIPLE_CHOICE.equals(question.getPatternCode())
                && question.getItemList() != null) {
            
            List<Item> itemList = question.getItemList();
            List<Item> generatedItemList = new ArrayList<Item>();
            Iterator<Item> iterator = itemList.iterator();
            
            while(iterator.hasNext()) {
                Item item = iterator.next();
                
                if(!"".equals(item.getContent()) && item.getContent() != null) {
                    item.setSid(KeyGenerator.generatorKey());
                    item.setQuestionSid(question.getSid());
                    item.setUseYn(OsdevConstants.USE_YES);
                    generatedItemList.add(item);
                }
            }
            
            itemDao.addList(generatedItemList);
        }
        
        if (question.getCommentary() != null && StringUtils.isNotEmpty(question.getCommentary().getDescription())) {
            Commentary commentary = question.getCommentary();
            commentary.setSid(generatedKey);
            commentary.setQuestionSid(question.getSid());
            commentary.setUseYn(OsdevConstants.USE_YES);
            
            commentaryDao.add(commentary);
        }
        
        return question;
    }

    @Override
    public int count() throws DataAccessException {
        return questionDao.count();
    }

    @Override
    public Question find(Question question) throws DataAccessException {
        Question findQuestion = questionDao.find(question);
        
        findQuestion.setAnswer(answerDao.findByQuestion(question));
        findQuestion.setItemList(itemDao.findListByQuestion(question));
        findQuestion.setCommentary(commentaryDao.findByQuestion(question));
        
        return findQuestion;
    }

    @Override
    public List<Question> findList(Map<String, Object> parameter) throws DataAccessException {
        return questionDao.findList(parameter);
    }
    
    @Override
    public List<Question> findShareList(User user, Map<String, Object> parameter) throws DataAccessException {
        return questionDao.findShareList(user, parameter);
    }
    
    @Override
    public List<Question> findList(User user, Map<String, Object> parameter) throws DataAccessException {
        return questionDao.findList(user, parameter);
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    @Override
    public Question modify(Question question) throws DataAccessException {
        questionDao.modify(question);
        
        if (question.getAnswer() != null) {
            Answer answer = question.getAnswer();
            answer.setAnswerCode(question.getPatternCode());
            answer.setUseYn(OsdevConstants.USE_YES);
            
            answerDao.modify(answer);
        }
        
        if (OsdevConstants.CLASSCIFICATION_CODE_MULTIPLE_CHOICE.equals(question.getPatternCode())
                && question.getItemList() != null) {
            
            List<Item> itemList = question.getItemList();
            List<Item> generatedItemList = new ArrayList<Item>();
            Iterator<Item> iterator = itemList.iterator();
            
            while(iterator.hasNext()) {
                Item item = iterator.next();
                item.setSid(KeyGenerator.generatorKey());
                item.setQuestionSid(question.getSid());
                item.setUseYn(OsdevConstants.USE_YES);
                generatedItemList.add(item);
            }
            
            itemDao.addList(generatedItemList);
        }
        
        if (question.getCommentary() != null && StringUtils.isNotEmpty(question.getCommentary().getDescription())) {
            Commentary commentary = question.getCommentary();
            commentary.setUseYn(OsdevConstants.USE_YES);
            
            if(commentaryDao.modify(commentary) == 0) {
                String generatedKey = KeyGenerator.generatorKey();

                commentary.setSid(generatedKey);
                commentary.setQuestionSid(question.getSid());
                
                commentaryDao.add(commentary);
            }
        }
        
        return question;
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    @Override
    public Question remove(Question question) throws DataAccessException {
        questionDao.remove(question);
        
        if(answerDao.removeByQuestion(question) > 0);
        if (OsdevConstants.CLASSCIFICATION_CODE_MULTIPLE_CHOICE.equals(question.getPatternCode())
                && itemDao.removeByQuestion(question) > 0);
        
        return question;
    }
}
